home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / UTILITIE / CONVERSI / 1396.ZIP / DATETRAN.C < prev    next >
C/C++ Source or Header  |  1988-03-20  |  12KB  |  437 lines

  1. /*
  2.  * datetran.c
  3.  *
  4.  * Translate various forms of dates into other forms
  5.  *
  6.  *    Usage is :
  7.  *        datetran in_file out_file in_format out_format
  8.  *
  9.  *    1) in_file is the file to be translated
  10.  *    2) out_file is the file to be created
  11.  *    3) in_format is the way the dates look in 'in_file' that you want changed
  12.  *    4) out_format is the way you want the dates to look in 'out_file'
  13.  *
  14.  *    in_format and out_format are formed as follows :
  15.  *        1) the format must be exactly 8 characters long
  16.  *        2) the letters DD or dd must appear in the format
  17.  *        3) the letters MM or mm must appear in the format
  18.  *        4) the letters YY or yy must appear in the format
  19.  *        5) some form of punctuation must appear in the 3rd & 6th
  20.  *            positions of the format
  21.  *        examples :
  22.  *            mm/dd/yy  mm.dd.yy  yy*dd*mm MMxDDxYY
  23.  *        note that you are restricted ONLY in that you may note use
  24.  *        the letters 'm', 'd', 'y', (or their upper case versions) as
  25.  *        punctuation, and that both punctuations must be the same
  26.  *
  27.  * Recommended compilation procedure using Manx Aztec C86-d :
  28.  *        cc -E1000 -Z3000 datetran.c
  29.  *        ln datetran.o -lc
  30.  *
  31.  * Released to the public domain March 20, 1988
  32.  * Bill Leary
  33.  * Co-Sysop, Cul-de-Sac TBBS, Holliston, Mass.
  34.  * (617)429-1784 300/1200/2400 baud, 8 bits, 1 stop bit, no parity
  35.  */
  36. #include <stdio.h>
  37. #include <ctype.h>
  38.  
  39. extern long ftell();
  40.  
  41. void usage( s )
  42. char *s;
  43. {
  44.     fprintf( stderr, "\nERROR : %s\n", s );
  45.     fprintf( stderr, "\n Try     datetran help\n\007" );
  46.     exit( -1 );
  47. }
  48.  
  49. void help()
  50. {
  51.     printf( "\n\n\n\n\n\n" );
  52.     printf( "DATETRAN :\n" );
  53.     putchar( '\n' );
  54.     printf( " This program will read a text file line by line and change\n" );
  55.     printf( "all occurances of dates in one user specified form into\n" );
  56.     printf( "dates of another user specified form.\n" );
  57.     putchar( '\n' );
  58.     printf( " The program expects to be given four parameters :\n" );
  59.     printf( "   1) The name of the file to be converted.\n" );
  60.     printf( "   2) The name of a file the program will create\n" );
  61.     printf( "      which will become a copy of the original file\n" );
  62.     printf( "      except for the changed formats of the dates.\n" );
  63.     printf( "   3) A format (or 'picture') of how the dates in\n" );
  64.     printf( "      the original file are now formed.\n" );
  65.     printf( "   4) A format of how you want the dates in\n" );
  66.     printf( "      the new file to be formed.\n" );
  67.     putchar( '\n' );
  68.     printf( " The correct way to start this program is :\n" );
  69.     putchar( '\n' );
  70.     printf( "   datetran original_file new_file original_format new_format\n" );
  71.     printf( "\n-- press Enter to continue --" );
  72.     fflush( stdout );
  73.     while ( getchar() != '\n' )
  74.         ;
  75.     printf( "\n\n\n\n\n\n" );
  76.     printf( " The file names are the usual forms of file names, including\n" );
  77.     printf( "full support for paths.\n" );
  78.     putchar( '\n' );
  79.     printf( " The rules for files are :\n" );
  80.     printf( "  1) The original_file must already exist.\n" );
  81.     printf( "  2) The new_file must not exist.\n" );
  82.     printf( "  3) The original and new files must not be the same.\n" );
  83.     putchar( '\n' );
  84.     printf( " The rules for date formats (or 'pictures') are :\n" );
  85.     printf( "  1) The characters 'DD' or 'dd' must appear in the format.\n" );
  86.     printf( "  2) The characters 'MM' or 'mm' must appear in the format.\n" );
  87.     printf( "  3) The characters 'YY' or 'yy' must appear in the format.\n" );
  88.     printf( "  4) Each of the above character pairs must only be used\n" );
  89.     printf( "     once in the format.\n" );
  90.     printf( "  5) Some form of punctuation must appear between each of\n" );
  91.     printf( "     the character pairs.\n" );
  92.     printf( "  6) The characters 'M', 'm', 'D', 'd', 'Y' and 'y' are not\n" );
  93.     printf( "     permitted as punctuation in the format.\n" );
  94.     printf( "  7) The two punctuation characters must be the same.\n" );
  95.     putchar( '\n' );
  96.     printf( "  good examples : MM/DD/YY yy-dd-mm DDxMMxYY MM*DD*YY\n" );
  97.     printf( "  bad examples : M/DD/YYY MMmDDmYY mm-dd/yy DD/DD/YY\n" );
  98.     printf( "\n-- press Enter to continue --" );
  99.     fflush( stdout );
  100.     while ( getchar() != '\n' )
  101.         ;
  102.     printf( "\n\n\n\n\n\n\n" );
  103.     printf( "Example of use :\n" );
  104.     putchar( '\n' );
  105.     printf( "  datetran alpha.a beta.b mm/dd/yy yy-mm-dd\n" );
  106.     putchar( '\n' );
  107.     printf( "  Would read every line in 'alpha.a' and copy it to 'beta.b'.\n" );
  108.     printf( "  In the process any dates like 02/23/88 or 09/02/55 would\n" );
  109.     printf( "  translated into 88-02-23 and 55-09-02.\n" );
  110.     putchar( '\n' );
  111.     printf( "CAUTION : This program doesn't actually check to see that\n" );
  112.     printf( "  the parts of the date are legal. That is, it believes that\n" );
  113.     printf( "  any sequence of six digits, broken up by the punctuation\n" );
  114.     printf( "  you gave in 'original_format' is a date. It then uses the\n" );
  115.     printf( "  MM, DD and YY to decide how you want the digits swapped\n" );
  116.     printf( "  around. In the above example the sequence 88/99/11 would\n" );
  117.     printf( "  have been converted to 11-88-99.\n" );
  118.     putchar( '\n' );
  119.     printf( "end of help\n" );
  120.     exit( 0 );
  121. }
  122.  
  123. /* 
  124.  * issues an update to the operator telling him/her how we're doing
  125.  */
  126. void show_count( l, c )
  127. int l, c;
  128. {
  129.     printf( "\rlines = %d, corrections = %d", l, c );
  130.     fflush( stdout );
  131. }
  132.  
  133. /*
  134.  * returns -1 if given strings are equal
  135.  * returns 0 otherwise
  136.  *
  137.  * Is case insensitive
  138.  */
  139. int strckeq( a, b )
  140. char *a, *b;
  141. {
  142.     while ( *a )
  143.     {
  144.         if ( toupper( *a++ ) != toupper( *b++ ) )
  145.             return 0;
  146.     }
  147.     if ( *a || *b )
  148.         return 0;
  149.     return -1;
  150. }
  151.  
  152. void prep_date( date, MM_pos, DD_pos, YY_pos, P_char )
  153. char *date;
  154. int  *MM_pos, *DD_pos, *YY_pos;
  155. char *P_char;
  156. {
  157.     int i;
  158.     char temp[80];
  159.  
  160.     *MM_pos = 10;
  161.     *DD_pos = 10;
  162.     *YY_pos = 10;
  163.     *P_char = '\0';
  164.     for ( i = 0; i < 8; i++ )
  165.     {
  166.         if ( *(date+i) == 'M' )
  167.         {
  168.             if ( *(date+i+1) == 'M' )
  169.             {
  170.                 if ( *MM_pos != 10 )
  171.                     goto hopeless;
  172.                 if ( ( i != 0 ) && ( i != 3 ) && ( i != 6 ) )
  173.                     goto hopeless;
  174.                 *MM_pos = i;
  175.             }
  176.             if ( *MM_pos == 10 )
  177.                 goto hopeless;
  178.             continue;
  179.         }
  180.         if ( *(date+i) == 'D' )
  181.         {
  182.             if ( *(date+i+1) == 'D' )
  183.             {
  184.                 if ( *DD_pos != 10 )
  185.                     goto hopeless;
  186.                 if ( ( i != 0 ) && ( i != 3 ) && ( i != 6 ) )
  187.                     goto hopeless;
  188.                 *DD_pos = i;
  189.             }
  190.             if ( *DD_pos == 10 )
  191.                 goto hopeless;
  192.             continue;
  193.         }
  194.         if ( *(date+i) == 'Y' )
  195.         {
  196.             if ( *(date+i+1) == 'Y' )
  197.             {
  198.                 if ( *YY_pos != 10 )
  199.                     goto hopeless;
  200.                 if ( ( i != 0 ) && ( i != 3 ) && ( i != 6 ) )
  201.                     goto hopeless;
  202.                 *YY_pos = i;
  203.             }
  204.             if ( *YY_pos == 10 )
  205.                 goto hopeless;
  206.             continue;
  207.         }
  208.         if ( *P_char && ( *P_char != *(date+i) ) )
  209.             goto hopeless;
  210.         if ( ( i != 2 ) && ( i != 5 ) )
  211.             goto hopeless;
  212.         *P_char = *(date+i);
  213.     }
  214.     if ( ( *MM_pos == 10 ) || ( *DD_pos == 10 ) || ( *YY_pos == 10 ) )
  215.         goto hopeless;
  216.     if ( *P_char )
  217.         return;
  218. hopeless:
  219.     sprintf( temp, "%s isn't a correct date format", date );
  220.     usage( temp );
  221. }
  222.  
  223. main( argc, argv)
  224. int argc;
  225. char *argv[];
  226. {
  227.     FILE *in_file, *out_file;
  228.     char  line[1000];
  229.     char  c;
  230.     char *cp;
  231.     int   i, j;
  232.     int   ic;
  233.     long  position;
  234.     int   exchange;
  235.     int   lines = 0;
  236.     int   corrections = 0;
  237.     char  old[10];
  238.     char  new[10];
  239.     int   old_MM_pos;
  240.     int   old_DD_pos;
  241.     int   old_YY_pos;
  242.     char  old_P_char;
  243.     int   new_YY_pos;
  244.     int   new_MM_pos;
  245.     int   new_DD_pos;
  246.     char  new_P_char;
  247.  
  248.     /*
  249.      * check for attempt to get help first
  250.      */
  251.     if ( ( argc == 2 ) && ( strlen( argv[1] ) == 4 ) )
  252.     {
  253.         for ( i = 0; i < strlen( argv[1] ); i++ )
  254.             if ( islower( argv[1][i] ) )
  255.                 new[i] = toupper( argv[1][i] );
  256.             else
  257.                 new[i] = argv[1][i];
  258.         new[i] = '\0';
  259.         if ( strcmp( new, "HELP" ) == 0 )
  260.             help();
  261.     }
  262.  
  263.     /*
  264.      * make sure
  265.      *    there are EXACTLY FOUR arguments
  266.      *    the first and second are file names
  267.      *    the two file names are NOT the same
  268.      *    the first file DOES exist
  269.      *    the second file DOESN'T exist
  270.      *    the third and fourth are date formats
  271.      *    the two date formats are NOT the same
  272.      */
  273.     if ( argc < 5 )
  274.         usage( "not enough arguments" );
  275.     if ( argc > 5 )
  276.         usage( "too many arguments" );
  277.     if ( strckeq( argv[1], argv[2] ) )
  278.         usage( "source and destination file names are the same" );
  279.     if ( access( argv[1], 0 ) )
  280.     {
  281.         sprintf( line, "can't find %s", argv[1] );
  282.         usage( line );
  283.     }
  284.     if ( access( argv[1], 4 ) )
  285.     {
  286.         sprintf( line, "can't open %s for read", argv[1] );
  287.         usage( line );
  288.     }
  289.     if ( access( argv[2], 0 ) == 0 )
  290.     {
  291.         sprintf( line, "%s already exists", argv[2] );
  292.         usage( line );
  293.     }
  294.     if ( strlen( argv[3] ) != 8 )
  295.     {
  296.         sprintf( line, "old_format, %s,isn't 8 characters long", argv[3] );
  297.         usage( line );
  298.     }
  299.     if ( strlen( argv[4] ) != 8 )
  300.     {
  301.         sprintf( line, "new_format, %s,isn't 8 characters long", argv[4] );
  302.         usage( line );
  303.     }
  304.  
  305.     /*
  306.      * convert formats to uppercase and store locally
  307.      */
  308.     for ( i = 0; i < 8; i++ )
  309.     {
  310.         old[i] = *(argv[3]+i);
  311.         if ( islower( old[i] ) )
  312.             old[i] = toupper( old[i] );
  313.         new[i] = *(argv[4]+i);
  314.         if ( islower( new[i] ) )
  315.             new[i] = toupper( new[i] );
  316.     }
  317.     old[i] = '\0';
  318.     new[i] = '\0';
  319.  
  320.     /*
  321.      * validate old and new date formats and set up for conversions
  322.      */
  323.     prep_date( old, &old_MM_pos, &old_DD_pos, &old_YY_pos, &old_P_char );
  324.     prep_date( new, &new_MM_pos, &new_DD_pos, &new_YY_pos, &new_P_char );
  325.  
  326.     /*
  327.      * make sure date formats aren't the same
  328.      */
  329.     if ( strcmp( old, new ) == 0 )
  330.         usage( "both date formats are the same" );
  331.  
  332.     /*
  333.      * open source file for read only
  334.      */
  335.     if ( ( in_file = fopen( argv[1], "r" ) ) == (FILE *)0 )
  336.     {
  337.         sprintf( line, "can't open %s", argv[1] );
  338.         usage( line );
  339.     }
  340.  
  341.     /*
  342.      * open destination file for write only
  343.      */
  344.     if ( ( out_file = fopen( argv[2], "w" ) ) == (FILE *)0 )
  345.     {
  346.         sprintf( line, "can't create %s", argv[2] );
  347.         usage( line );
  348.     }
  349.  
  350.     /*
  351.      * tell operator what we're doing
  352.      */
  353.     printf( "\nInput file : %s\n", argv[1] );
  354.     printf( "Output file: %s\n", argv[2] );
  355.     printf( "Translating %s to %s\n", old, new );
  356.     show_count( lines, corrections );
  357.  
  358.     /*
  359.      * read each line, replacing any old format dates with new
  360.      *    format dates
  361.      */
  362.     ic = 'x';
  363.     while ( 1 )
  364.     {
  365.         /*
  366.          * if we saw end of file last time around, we're done
  367.          */
  368.         if ( ic == EOF )
  369.             break;
  370.  
  371.         /*
  372.          * get ready to read line
  373.          */
  374.         i = 0;
  375.         cp = (char *)0;
  376.  
  377.         /*
  378.          * read line
  379.          */
  380.         while ( ( ic = fgetc( in_file ) ) != EOF )
  381.         {
  382.             if ( ic == '\r' )
  383.                 continue;
  384.             line[i++] = (char)ic;
  385.             if ( ic == '\n' )
  386.                 break;
  387.         }
  388.         line[i] = '\0';
  389.  
  390.         if ( ic != EOF )
  391.             lines++;
  392.  
  393.         /*
  394.          * find date patterns in this line
  395.          */
  396.         for ( i = 0; i < strlen( line ) - 8; i++ )
  397.         {
  398.             if ( isdigit( line[i] ) && isdigit( line[i+1] )
  399.               && isdigit( line[i+3] ) && isdigit( line[i+4] )
  400.               && isdigit( line[i+6] ) && isdigit( line[i+7] )
  401.               && ( line[i+2] == old_P_char )
  402.               && ( line[i+5] == old_P_char ) )
  403.             {
  404.                 corrections++;
  405.                 new[new_MM_pos]   = line[i+old_MM_pos];
  406.                 new[new_MM_pos+1] = line[i+old_MM_pos+1];
  407.                 new[new_DD_pos]   = line[i+old_DD_pos];
  408.                 new[new_DD_pos+1] = line[i+old_DD_pos+1];
  409.                 new[new_YY_pos]   = line[i+old_YY_pos];
  410.                 new[new_YY_pos+1] = line[i+old_YY_pos+1];
  411.                 new[2] = new_P_char;
  412.                 new[5] = new_P_char;
  413.                 for ( j = 0; j < 8; j++ )
  414.                     line[i+j] = new[j];
  415.             }
  416.         }
  417.  
  418.         /*
  419.          * output possibly corrected line
  420.          */
  421.         fprintf( out_file, "%s", line );
  422.  
  423.         /*
  424.          * give progress messages to pacify the operator
  425.          */
  426.         if ( ( lines & 0x000f ) == 0 )
  427.             show_count( lines, corrections );
  428.     }
  429.     show_count( lines, corrections );
  430.  
  431.     fclose( in_file );
  432.     fclose( out_file );
  433.  
  434.     printf( "\nDone\n" );
  435. }
  436.  
  437.